package com.lgl.allpeoplevent.ventIndex.service;

import com.lgl.allpeoplevent.util.service.UtilService;
import com.lgl.scsapi.base.dao.DaoSupport;
import com.lgl.scsapi.system.model.PageData;
import com.lgl.scsapi.util.utils.Constants;
import com.lgl.scsapi.vent.model.VentUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Slf4j
@Service
public class VentUserService {
    @Autowired
    private DaoSupport dao;
    @Autowired
    private UtilService utilService;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 判断手机号是否已存在
     * @param ventPhone 手机号参数
     * @return true:存在，false:不存在
     */
    public boolean existsVentPhone(String ventPhone){
        if (!StringUtils.hasText(ventPhone)){
            return false;
        }
        PageData phonePd = (PageData)dao.findForObject("VentUserMapper.existsVentPhone", ventPhone);
        return phonePd != null && !phonePd.isEmpty();
    }
    /**
     * 判断手机号是否已存在
     * @param userPhone 手机号参数
     * @return true:存在，false:不存在
     */
    public VentUser findByPhone(String userPhone){
        if (!StringUtils.hasText(userPhone)){
            return null;
        }
        return (VentUser) dao.findForObject("VentUserMapper.findByPhone", userPhone);
    }
    /**
     * 保存吐槽用户
     * @param pd 要保存的用户参数
     * @return 影响的行数
     */
    public int saveVentUser(PageData pd) {
        return dao.save("VentUserMapper.saveVentUser", pd);
    }
    /**
     * 通过用户名和密码获取用户
     * @param pd 用户名和密码
     * @return 用户对象
     */
    public VentUser findByNameAndPassword(PageData pd) {
        return (VentUser)dao.findForObject("VentUserMapper.findByNameAndPassword", pd);
    }

    /**
     * 登录
     * @param paramPd 登录参数
     * @return 登录结果
     */
    public PageData toLogin(PageData paramPd){
        String userName = paramPd.getString("userName");
        String userPassword = paramPd.getString("userPassword");
        if(StringUtils.isEmpty(userName) || StringUtils.isEmpty(userPassword)){
            paramPd.clear();
            paramPd.put("status", "1");
            return paramPd;
        }
        String hashPassword = new SimpleHash(Constants.ALGORITHM_NAME,userPassword, Constants.SHIRO_SALT,Constants.HASH_ITERATIONS).toHex();
        paramPd.put("userName", userName);
        paramPd.put("userPassword", hashPassword);
        VentUser user = findByNameAndPassword(paramPd);
        paramPd.clear();
        if(user == null){
            paramPd.put("status", "3");
            return paramPd;
        }
        user.setUserName(userName).setPassword(userPassword);
        //用户已冻结
        if("1".equals(user.getStatus())){
            paramPd.put("status", "5");
            return paramPd;
        }
        return execLoginReturnResult(paramPd,user);
    }

    /**
     * 执行登录，并返回用户信息结果
     * @return 包含用户信息的PageData
     */
    public PageData execLoginReturnResult(PageData userPd,VentUser ventUser){
        userPd.put("status", "0");//验证成功
        userPd.put("userPhone", ventUser.getPhone() == null ? "" : ventUser.getPhone());
        userPd.put("userId", ventUser.getUserId());
        userPd.put("userName", ventUser.getUserName());
        userPd.put("nickName", ventUser.getNickName());
        userPd.put("sex", String.valueOf(ventUser.getSex()));
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(ventUser.getUserName(), ventUser.getPassword(),true);
        try {
            token.setRememberMe(true);
            subject.login(token);
            //清空缓存中的用户密码，以减少密码占用缓存空间
            ventUser.setPassword(null);
            subject.getSession().setAttribute(Constants.SESSION_USER, ventUser);
            utilService.asyncSetLoginStatus(ventUser.getUserId());
        } catch (AuthenticationException e) {
            userPd.put("status", "4");
            log.error(e.toString(),e);
        }
        return userPd;
    }

    /**
     * 获取“他的主页”中的用户信息
     * @param pd 查询参数
     * @param isEncryption 是否对邮箱、生日等数据作脱敏处理，true:脱敏处理，false:不处理
     * @return VentUser对象
     */
    public VentUser getHisInfo(PageData pd,boolean isEncryption) {
        VentUser his = (VentUser)dao.findForObject("VentUserMapper.getHisInfo", pd);
        if (isEncryption){
            String email = his.getEmail();
            email = email.substring(0,2) + "***" + email.substring(email.indexOf("@"));
            his.setEmail(email);
            String birthday = his.getBirthday();
            his.setBirthday(birthday.substring(0,2));
        }
        return his;
    }
    /**
     * 修改吐槽用户信息
     * @param editPd 修改的相关参数
     * @return 成功的行数
     */
    public Integer editVentUser(PageData editPd){
        return dao.update("VentUserMapper.editVentUser", editPd);
    }

    /**
     * 修改我的手机号
     * @param ventUser 登录用户
     * @param userNewPhone 新手机号
     * @param checkCode 验证码
     * @return 校验、成功、失败码
     */
    public String modifyMyPhone(VentUser ventUser, String userNewPhone, String checkCode){
        if (ventUser == null){
            return "3";
        }
        if (!StringUtils.hasText(userNewPhone)) {
            return "6";
        }
        if (!StringUtils.hasText(checkCode)) {
            return "4";
        }
        String oldPhone = ventUser.getPhone();
        //如果新手机号=原手机号
        if (userNewPhone.equals(oldPhone)) {
            return "7";
        }
        String redisCheckCode = stringRedisTemplate.opsForValue().get(Constants.PHONE_CHECK_CODE_K_PRE + ventUser.getPhone());
        if (!checkCode.equals(redisCheckCode)) {
            return "5";
        }
        //如果新手机号已存在
        if (existsVentPhone(userNewPhone)){
            return "2";
        }
        PageData modifyPhonePd = new PageData(6);
        modifyPhonePd.put("newPhone", userNewPhone);
        modifyPhonePd.put("userId",ventUser.getUserId());
        modifyPhonePd.put("oldPhone", oldPhone);
        int row = dao.update("VentUserMapper.editMyPhone", modifyPhonePd);
        return row > 0 ? "0" : "2";
    }
    /**
     * 修改用户头像
     * @param editPd 修改的相关参数
     * @return 成功的行数
     */
    public int editHeaderImg(PageData editPd){
        return dao.update("VentUserMapper.editHeaderImg", editPd);
    }
    /**
     * 判断手机号是否已存在
     * @param userId 手机号参数
     * @return true:存在，false:不存在
     */
    public String getHeaderImgPath(String userId){
        if (!StringUtils.hasText(userId)){
            return null;
        }
        PageData imgPd = (PageData)dao.findForObject("VentUserMapper.getHeaderImgPath", userId);
        if(imgPd == null || imgPd.isEmpty()){
            return null;
        }
        return imgPd.getString("header_img_path");
    }
    /**
     * 通过验证码修改密码
     * @param myPhone 手机号
     * @param newPwd 新密码
     * @param checkCode 验证码
     * @return 修改的成功/失败状态
     */
    public PageData modifyPwdByCheckCode(String myPhone,String newPwd,String checkCode){
        PageData modifyPwdPd = new PageData(3);
        if (!StringUtils.hasText(myPhone) || !StringUtils.hasText(newPwd)) {
            modifyPwdPd.put("status", !StringUtils.hasText(myPhone) ? "3" : "4");
            return modifyPwdPd;
        }
        if (!StringUtils.hasText(checkCode)) {
            modifyPwdPd.put("status", "2");
            return modifyPwdPd;
        }
        String phoneKey = Constants.PHONE_CHECK_CODE_K_PRE + myPhone;
        //从redis中取验证码，并与传过来的比较
        String redisCheckCode = stringRedisTemplate.opsForValue().get(phoneKey);
        if (!checkCode.equals(redisCheckCode)) {
            modifyPwdPd.put("status", "5");
            return modifyPwdPd;
        }
        newPwd = new SimpleHash(Constants.ALGORITHM_NAME,newPwd,Constants.SHIRO_SALT,Constants.HASH_ITERATIONS).toHex();
        modifyPwdPd.put("newPwd", newPwd);
        modifyPwdPd.put("myPhone", myPhone);
        dao.update("VentUserMapper.editMyPwd", modifyPwdPd);
        //editMyOtherInfo(modifyPwdPd);
        //redisTemplate.delete(phoneKey);
        stringRedisTemplate.delete(phoneKey);
        modifyPwdPd.clear();
        modifyPwdPd.put("status", "0");
        return modifyPwdPd;
    }
    /**
     * 通过旧密码修改密码
     * @param myPhone 手机号
     * @param newPwd 新密码
     * @param oldPwd 旧密码
     * @return 修改的成功/失败状态
     */
    public PageData modifyPwdByOld(String myPhone,String newPwd,String oldPwd){
        PageData modifyPwdPd = new PageData(3);
        if (!StringUtils.hasText(newPwd)) {
            modifyPwdPd.put("status","4");
            return modifyPwdPd;
        }
        if (!StringUtils.hasText(oldPwd)) {
            modifyPwdPd.put("status", "2");
            return modifyPwdPd;
        }

        newPwd = new SimpleHash(Constants.ALGORITHM_NAME,newPwd,Constants.SHIRO_SALT,Constants.HASH_ITERATIONS).toHex();
        modifyPwdPd.put("newPwd", newPwd);
        modifyPwdPd.put("oldPwd", oldPwd);
        modifyPwdPd.put("myPhone", myPhone);
        dao.update("VentUserMapper.editMyPwd", modifyPwdPd);
        modifyPwdPd.clear();
        modifyPwdPd.put("status", "0");
        return modifyPwdPd;
    }
}